/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// dict.h - entity dictionary library
//


#ifndef __GAME_DICT_H__
#define __GAME_DICT_H__


#define KEY_VALUES_HASH_SIZE			8

struct keyValue_t {
	const char *			key;
	const char *			value;

	keyValue_t *			next;
	keyValue_t *			nextHash;
};

class etDict {
private:
	keyValue_t *			keyValues;
	keyValue_t *			keyValuesHashTable[KEY_VALUES_HASH_SIZE];

public:
							etDict ();
							~etDict ();

	etDict &				operator = (const etDict &dict);

	int						Size () const;

	void					Clear ();

	bool					Parse (script_t *script);
	void					Write (fileHandle_t f) const;

	bool					ParseKeyValue (script_t *script);
	void					WriteKeyValues (fileHandle_t f) const;

	void					ListKeyValues () const;

	int						NumKeyValues () const;
	const keyValue_t *		GetKeyValue (int index) const;

	void					AddKeyValue (const char *key, const char *value);
	void					RemoveKeyValue (const char *key);

	const keyValue_t *		FindKeyValue (const char *key) const;
	keyValue_t *			FindKeyValue (const char *key);

	const keyValue_t *		MatchPrefix (const char *prefix, const keyValue_t *lastMatch = NULL) const;

	void					SetString (const char *key, const char *value);
	void					SetBool (const char *key, bool value);
	void					SetInteger (const char *key, int value);
	void					SetFloat (const char *key, float value);
	void					SetVec2 (const char *key, const glqVec2 &value);
	void					SetVec3 (const char *key, const glqVec3 &value);
	void					SetVec4 (const char *key, const glqVec4 &value);
	void					SetVec5 (const char *key, const glqVec5 &value);
	void					SetAngles (const char *key, const glqAngles &value);
	void					SetQuat (const char *key, const glqQuat &value);
	void					SetMat3 (const char *key, const glqMat3 &value);
	void					SetMat4 (const char *key, const glqMat4 &value);

	const char *			GetString (const char *key, const char *defaultValue = "") const;
	bool					GetBool (const char *key, const char *defaultValue = "0") const;
	int						GetInteger (const char *key, const char *defaultValue = "0") const;
	float					GetFloat (const char *key, const char *defaultValue = "0") const;
	glqVec2					GetVec2 (const char *key, const char *defaultValue = "0 0") const;
	glqVec3					GetVec3 (const char *key, const char *defaultValue = "0 0 0") const;
	glqVec4					GetVec4 (const char *key, const char *defaultValue = "0 0 0 0") const;
	glqVec5					GetVec5 (const char *key, const char *defaultValue = "0 0 0 0 0") const;
	glqAngles				GetAngles (const char *key, const char *defaultValue = "0 0 0") const;
	glqQuat					GetQuat (const char *key, const char *defaultValue = "0 0 0 1") const;
	glqMat3					GetMat3 (const char *key, const char *defaultValue = "1 0 0 0 1 0 0 0 1") const;
	glqMat4					GetMat4 (const char *key, const char *defaultValue = "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1") const;

	bool					GetString (const char *key, const char **value, const char *defaultValue = "") const;
	bool					GetBool (const char *key, bool *value, const char *defaultValue = "0") const;
	bool					GetInteger (const char *key, int *value, const char *defaultValue = "0") const;
	bool					GetFloat (const char *key, float *value, const char *defaultValue = "0") const;
	bool					GetVec2 (const char *key, glqVec2 &value, const char *defaultValue = "0 0") const;
	bool					GetVec3 (const char *key, glqVec3 &value, const char *defaultValue = "0 0 0") const;
	bool					GetVec4 (const char *key, glqVec4 &value, const char *defaultValue = "0 0 0 0") const;
	bool					GetVec5 (const char *key, glqVec5 &value, const char *defaultValue = "0 0 0 0 0") const;
	bool					GetAngles (const char *key, glqAngles &value, const char *defaultValue = "0 0 0") const;
	bool					GetQuat (const char *key, glqQuat &value, const char *defaultValue = "0 0 0 1") const;
	bool					GetMat3 (const char *key, glqMat3 &value, const char *defaultValue = "1 0 0 0 1 0 0 0 1") const;
	bool					GetMat4 (const char *key, glqMat4 &value, const char *defaultValue = "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1") const;
};

INLINE const char *etDict::GetString (const char *key, const char *defaultValue) const {

	const char	*value;

	GetString(key, &value, defaultValue);

	return value;
}

INLINE bool etDict::GetBool (const char *key, const char *defaultValue) const {

	bool	value;

	GetBool(key, &value, defaultValue);

	return value;
}

INLINE int etDict::GetInteger (const char *key, const char *defaultValue) const {

	int		value;

	GetInteger(key, &value, defaultValue);

	return value;
}

INLINE float etDict::GetFloat (const char *key, const char *defaultValue) const {

	float	value;

	GetFloat(key, &value, defaultValue);

	return value;
}

INLINE glqVec2 etDict::GetVec2 (const char *key, const char *defaultValue) const {

	glqVec2	value;

	GetVec2(key, value, defaultValue);

	return value;
}

INLINE glqVec3 etDict::GetVec3 (const char *key, const char *defaultValue) const {

	glqVec3	value;

	GetVec3(key, value, defaultValue);

	return value;
}

INLINE glqVec4 etDict::GetVec4 (const char *key, const char *defaultValue) const {

	glqVec4	value;

	GetVec4(key, value, defaultValue);

	return value;
}

INLINE glqVec5 etDict::GetVec5 (const char *key, const char *defaultValue) const {

	glqVec5	value;

	GetVec5(key, value, defaultValue);

	return value;
}

INLINE glqAngles etDict::GetAngles (const char *key, const char *defaultValue) const {

	glqAngles	value;

	GetAngles(key, value, defaultValue);

	return value;
}

INLINE glqQuat etDict::GetQuat (const char *key, const char *defaultValue) const {

	glqQuat	value;

	GetQuat(key, value, defaultValue);

	return value;
}

INLINE glqMat3 etDict::GetMat3 (const char *key, const char *defaultValue) const {

	glqMat3	value;

	GetMat3(key, value, defaultValue);

	return value;
}

INLINE glqMat4 etDict::GetMat4 (const char *key, const char *defaultValue) const {

	glqMat4	value;

	GetMat4(key, value, defaultValue);

	return value;
}


#endif	// __GAME_DICT_H__